#!/bin/bash

#****************************************************************#
# ScriptName: quickstart.sh
# Author: xiebaoyou@kernelsoft.com
# Create Date: 2022-09-15 15:53
#
# Modify Author: xiebaoyou@kernelsoft.com
# Modify Date: 2022-09-15 15:53
# Function: 常用脚本功能集合，使用方法:
#    执行默认功能，编译并运行photon-rtos
#			bash quickstart.sh
#    以sh quickstart.sh + 函数名的方式，调用执行某个子功能，例如：
#			bash quickstart.sh lines       	统计代码行数
# 注意：可以向函数传递参数，例如：
#			bash quickstart.sh check init/main.c
#
# Modify Author: huzicheng@kernelsoft.com
# Modify Date: 2023-02-13 14:37
# Function: 适配脚本到PhotonRTOS中。
#***************************************************************#

PWD="`pwd`"
if [ -z $ARCH ]; then
	ARCH="arm"
fi

if [ -z $MACH ]; then
	MACH="mps2_m3"
fi

if [ $ARCH == "arm" ]; then
	CROSS_COMPILE=`pwd`/../toolchains/gcc-arm-none-eabi-8-2018-q4-major/bin/arm-none-eabi-
fi

#
# 调试用，使用方法sh quickstart.sh test balabala balaba
#
function test()
{
	echo "xby-debug: 这是调试函数，参数：" $*
}

#
# 统计代码行数
#
function lines()
{
	dirs=(apps arch autosar drivers include init kernel lib)
	c_lines=0
	s_lines=0
	h_lines=0

	#
	# 分别统计每个子目录中的代码行
	#
	for dir in ${dirs[@]}; do
		echo "DIR: "$dir

		c_line=`find $dir -name *.c | while read line; do wc $line; done | awk '{print $1}' | awk '{sum += $1};END {print sum}'`
		s_line=`find $dir -name *.S | while read line; do wc $line; done | awk '{print $1}' | awk '{sum += $1};END {print sum}'`
		h_line=`find $dir -name *.h | while read line; do wc $line; done | awk '{print $1}' | awk '{sum += $1};END {print sum}'`
		let "c_lines=$c_line+$c_lines"
		let "s_lines=$s_line+$s_lines"
		let "h_lines=$h_line+$h_lines"

		echo " *.c "$c_line
		echo " *.s "$s_line
		echo " *.h "$h_line
	done

	#
	# 输出所有目录中总的代码行
	#
	echo "代码总量："
	echo " *.c: " $c_lines
	echo " *.s: " $s_lines
	echo " *.h: " $h_lines
	echo "已经分配的代码行："
	#
	# 已经分配到人头的代码
	# 注意其中 -iL 参数的使用
	#
	for i in `find ./ -regex ".*\.c\|.*\.h\|.*\.S" -print0 | xargs -0 grep -iL "kernelsoft.com\|iscas.ac.cn\|aliyun.com"`; do cat $i; done | wc -l
	echo " *.c"
	for i in `find ./ -regex ".*\.c" -print0 | xargs -0 grep -il "kernelsoft.com\|iscas.ac.cn\|aliyun.com"`; do cat $i; done | wc -l
	echo " *.s"
	for i in `find ./ -regex ".*\.S" -print0 | xargs -0 grep -il "kernelsoft.com\|iscas.ac.cn\|aliyun.com"`; do cat $i; done | wc -l
	echo " *.h"
	for i in `find ./ -regex ".*\.h" -print0 | xargs -0 grep -il "kernelsoft.com\|iscas.ac.cn\|aliyun.com"`; do cat $i; done | wc -l
}

function docloc()
{
	cloc ./ --fullpath --not-match-d=scripts
}

#
# 统计每个人在每个目录下的代码行
#
function guy()
{
	dirs=(apps arch autosar drivers include init kernel lib)
	guys=(huzicheng@kernelsoft.com liangjiayuan@kernelsoft.com s-yanglin.kernelsoft.com \
			dongxueming@kernelsoft.com s-zhangyili@kernelsoft.com xiebaoyou@kernelsoft.com \
			baoyou.xie@aliyun.com w-pengdong@kernelsoft.com)

	for man in ${guys[@]}; do
		echo "GUY: "$man
		for dir in ${dirs[@]}; do
			echo "  DIR: "$dir
			files=`grep -nr "$man" $dir | awk -F ":" '{print $1}'`
			lines=`for i in $files; do cat $i; done | wc -l`;

			echo "    Linies: "$lines
		done
	done
}

#
# 统计还没有分配到人的文件
#
function owner()
{
	dirs=(apps arch autosar drivers include init kernel lib)

	for dir in ${dirs[@]}; do
		echo "  DIR: "$dir "has no owner!!!!"
		find ./$dir -regex ".*\.c\|.*\.h\|.*\.S" -print0 | xargs -0 grep -iL "kernelsoft.com\|iscas.ac.cn\|aliyun.com"
	done
}

#
# 调用checkpatch.pl检查代码格式，例如：
#    sh quickstart.sh check init/main.c
#
function check()
{
	./scripts/checkpatch.pl -f --no-tree $*
}

function replace()
{
	sed -i "s/$1/$2/g" `grep -rl --exclude-dir=".git" --exclude="*.o" "$1" ./`
}

function distclean()
{
	make ARCH=$ARCH distclean
	make ARCH=$ARCH clean
}

#
# 清除编译生成的文件
#
function clean()
{
    make ARCH=$ARCH clean
}

function defconfig()
{
	make ARCH=$ARCH CROSS_COMPILE=$CROSS_COMPILE "$MACH"_defconfig
}

function menuconfig()
{
	make ARCH=$ARCH CROSS_COMPILE=$CROSS_COMPILE menuconfig
}

#
# 开发准备工作，第一次运行一下即可
#
function devel()
{
	echo $('pwd')/../toolchains
	if [ ! -f `dirname $0`/../toolchains/Makefile ]; then
		echo -e "项目外没有toolchains，请先获取toolchains\n\n\tgit clone --depth=1 https://gitee.com/kernelsoft/toolchains.git ../toolchains\n"
		exit 1
	fi

	cd `dirname $0`/../toolchains
	make
}

function run()
{
	if [ $ARCH == "arm" ]; then
		if [ $MACH == "zynqmp_r5" ]; then
			../toolchains/xilinx_qemu_env/qemu_xilinx/bin/qemu-system-aarch64 \
				-M arm-generic-fdt \
				-serial mon:stdio \
				-device loader,file=photon,cpu-num=4 \
				-device loader,addr=0XFF5E023C,data=0x80088fde,data-len=4 \
				-device loader,addr=0xff9a0000,data=0x80000218,data-len=4 \
				-device loader,addr=0xff9a0100,data=0x00000001,data-len=4 \
				-device loader,addr=0xff9a0200,data=0x00000001,data-len=4 \
				-hw-dtb ../toolchains/xilinx_qemu_env/LATEST/SINGLE_ARCH/zcu102-arm.dtb \
				-display none
		else
			qemu-system-arm -machine mps2-an385 -monitor null \
				-semihosting --semihosting-config enable=on,target=native \
				-serial stdio -nographic -kernel photon;
		fi
	fi
}

function debug()
{
	# 如果收到一行以end_line结束，则关闭虚拟机qemu
	end_line="关闭系统......"
	# 如果运行时间达到到max_time秒，则关闭虚拟机qemu
	max_time=40
	IFS=''

	clear
	defconfig

	`sleep $max_time;killall -q qemu-system-aarch64` & ARCH=arm MACH=zynqmp_r5 bash quickstart.sh | while read line
	do
		echo $line
		if [ "${line: (${#line} - ${#end_line} - 1) : ${#end_line}}" = "$end_line" ]; then
			echo ===================================关闭系统===================================
			killall -q qemu-system-aarch64
		fi
	done

	make clean
}

function rungdb()
{
    echo "gdb调试,请使用gdb连接"

	if [ $ARCH == "arm" ]; then
		if [ $MACH == "zynqmp_r5" ]; then
			../toolchains/xilinx_qemu_env/qemu_xilinx/bin/qemu-system-aarch64 \
				-M arm-generic-fdt \
				-serial mon:stdio \
				-device loader,file=photon,cpu-num=4 \
				-device loader,addr=0XFF5E023C,data=0x80088fde,data-len=4 \
				-device loader,addr=0xff9a0000,data=0x80000218,data-len=4 \
				-device loader,addr=0xff9a0100,data=0x00000001,data-len=4 \
				-device loader,addr=0xff9a0200,data=0x00000001,data-len=4 \
				-hw-dtb ../toolchains/xilinx_qemu_env/LATEST/SINGLE_ARCH/zcu102-arm.dtb \
				-display none \
				-S -gdb tcp::1234
		else
			qemu-system-arm -machine mps2-an385 -monitor null \
			-semihosting --semihosting-config enable=on,target=native \
			-serial stdio -nographic -kernel photon -S -gdb tcp::1234;
		fi
	fi
}

function compile()
{
	if [ $ARCH == "arm" ]; then
		make ARCH=arm EXTRA_CFLAGS="-g" \
		CROSS_COMPILE=$CROSS_COMPILE \
		Image dtbs;
	fi
}

#
# GDB调试简要说明
# 执行方法：sh quickstart.sh gdb
#
function gdb()
{
	make ARCH=$ARCH CROSS_COMPILE=$CROSS_COMPILE EXTRA_CFLAGS="-g" -j4 Image && rungdb && exit
}

#
# 默认执行此函数
# 注意：make和run之间用&&连接
# 这样编译错误的时候，不会运行
# 避免控制台中的编译错误被冲掉
#
function all()
{
	make ARCH=$ARCH CROSS_COMPILE=$CROSS_COMPILE \
		EXTRA_CFLAGS="-g -DCONFIG_OSEK=y" -j4 Image && run && exit
}

function usage()
{
	echo "请使用合适的参数"
	echo "使用方法:"
	echo "  执行默认功能，编译并运行photon-rtos"
	echo "      sh quickstart.sh"
	echo "  以sh quickstart.sh + 函数名的方式，调用执行某个子功能，例如："
	echo "      sh quickstart.sh lines       	统计代码行数"
	echo "注意：可以向函数传递参数，例如："
	echo "  sh quickstart.sh check init/main.c"
}

#
# 将字符串转换为函数，并调用函数
#
function call_sub_cmd()
{
	#
	# 通过第一个参数，获得想要调用的函数名
	# 例如 check 函数
	#
	func=$1
	#
	# 函数名不支持”-“，因此将参数中的”-“转换为”_“
	#
	func=${func//-/_}
	#
	# 从参数列表中移除第一个参数，例如 check，将剩余的参数传给函数
	#
	shift 1
	eval "$func $*"
}

#
# 主函数
#
function main()
{
	#
	# 如果没有任何参数，默认调用all函数
	#
	if [ $# -eq 0 ]; then
		all
		exit 0
	fi
	
	#
	# 带参数运行，看看相应的函数是否存在
	#
	SUB_CMD=$1
	type ${SUB_CMD//-/_} > /dev/null 2>&1
	#
	# 要调用的子函数不存在，说明用法错误
	#
	if [ $? -ne 0 ]; then
		usage
		exit
	else
		#
		# 要调用的子函数存在，执行子函数
		#
		shift 1;
		call_sub_cmd $SUB_CMD $*
		exit $?
	fi

	usage
}

#
# 调用主函数
#
main $*
